package cn.s1995.sloth.bizs.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.s1995.sloth.bizs.constant.BizCst;
import cn.s1995.sloth.bizs.constant.CacheNames;
import cn.s1995.sloth.bizs.entity.Prod;
import cn.s1995.sloth.bizs.entity.Shop;
import cn.s1995.sloth.bizs.entity.UserFollow;
import cn.s1995.sloth.bizs.entity.Video;
import cn.s1995.sloth.bizs.mapper.ProdMapper;
import cn.s1995.sloth.bizs.mapper.ShopMapper;
import cn.s1995.sloth.bizs.oo.vo.ShopDetailVO;
import cn.s1995.sloth.bizs.service.ShopService;
import cn.s1995.sloth.bizs.service.UserFollowService;
import cn.s1995.sloth.bizs.service.VideoService;
import cn.s1995.sloth.common.core.constant.enums.hint.Hint;
import cn.s1995.sloth.common.core.util.R;
import cn.s1995.sloth.common.core.util.SpringContextHolder;
import cn.s1995.sloth.common.security.util.SecurityUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 店铺
 *
 * @author Lex
 * @date 2023-12-12 08:25:47
 */
@Slf4j
@Service
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements ShopService {

    @Resource
    private UserFollowService userFollowService;

    @Resource
    private ProdMapper prodMapper;

    @Resource
	private VideoService videoService;

    @Override
    @Cacheable(cacheNames = CacheNames.shop, key = "#shopId")
    public Shop getShop(Long shopId) {
        return getById(shopId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = CacheNames.shop, key = "#shopDetail.shopId")
    public void updateShop(Shop shopDetail, Shop dbShopDetail) {

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = CacheNames.shop, key = "#shopId")
    public void removeShop(Long shopId) {
        removeById(shopId);
    }

    @Override
    @CacheEvict(cacheNames = CacheNames.shop, key = "#shopId")
    public void removeShopCache(Long shopId) {

    }

    @Override
    public R follow(Long id) {
        Shop shop = this.getById(id);
        if (ObjectUtil.isNull(shop))
            return R.failed(Hint.NOT_FOUND);
        // 判断是否已关注
        Long uid = SecurityUtils.getUser().getId();
        UserFollow follow = userFollowService.getOne(
                Wrappers.lambdaQuery(UserFollow.class)
                        .eq(UserFollow::getUid, uid)
                        .eq(UserFollow::getBindId, id)
                        .eq(UserFollow::getType, BizCst.UserFollow.Type.shop)
        );
        if (ObjectUtil.isNotNull(follow)) {
            // 已关注，取消
            userFollowService.removeById(follow);
        } else {
            // 关注
            userFollowService.save(
                    UserFollow.builder()
                            .type(BizCst.UserFollow.Type.shop)
                            .uid(uid)
                            .bindId(id)
                            .build()
            );
        }
        return R.ok();
    }

	@Override
	public ShopDetailVO getShopDetail(Long id) {
		ShopService shopService = SpringContextHolder.getBean(ShopService.class);
		Shop shop = shopService.getShop(id);
    	ShopDetailVO vo = BeanUtil.copyProperties(shop, ShopDetailVO.class);
    	vo.setProdCount(
			prodMapper.selectCount(
				Wrappers.lambdaQuery(Prod.class)
						.eq(Prod::getShopId, id)
						.eq(Prod::getIsSale, BizCst.CommonBool.yes)
			)
    	);
    	vo.setVideoCount(
    			videoService.count(
				Wrappers.lambdaQuery(Video.class)
						.eq(Video::getShopId, id)
						.eq(Video::getIsSale, BizCst.CommonBool.yes)
						.eq(Video::getState, BizCst.CommonAuditState.approve)
			)
    	);
    	vo.setFollowCount(
    			userFollowService.count(
				Wrappers.lambdaQuery(UserFollow.class)
						.eq(UserFollow::getType, BizCst.UserFollow.Type.shop)
						.eq(UserFollow::getBindId, id)
			)
    	);
    	return vo;
	}

	@Override
	public Page selectShopPage(Page page, Shop req) {
		return baseMapper.selectShopPage(page, req);
	}

}

